/*
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <QApplication>
#include <QHelpEvent>
#include <QToolTip>
#include <QList>
#include <QPainter>
#include <QTextEdit>
#include <QUrl>
#include <QTextBlock>
#include <QAbstractTextDocumentLayout>
#include <algorithm>
#include "postwidget.h"
#include "postitemview.h"
#include "components/thread.h"
#include "components/post.h"
#include "components/chan.h"
#include "log.h"
#include "extrainfo.h"

using Wishmaster::PostId;

PostWidget::PostWidget(Wishmaster::Board* b, const ThreadId& threadid, const PostId& postid, PostItemView* parent, bool hideImages, const PostStylePtr& style) : QWidget(0),
	m_piv(parent),
	m_sel(false),
	m_activeElement(pweUnknown),
	m_board(b),
	m_threadId(threadid),
	m_postId(postid),
	m_popup(0),
	m_popupChanged(false),
	m_chainLeader(false),
	m_inMMEvent(false),
	m_imageHideMode(hideImages)
{
	if(parent)
		setPostStyle(parent->postStyle());
	else
		setPostStyle(style);

	m_xynta = QFontMetrics(postStyle()->headerFont()).height() + 2 * ContentMargin;
	m_thread = b->getThread(threadid);
	if(!m_thread.isNull())
	{
		Wishmaster::PostPtr post = m_thread->lookupPost(postid);
		setText(post);
	}
	m_selection = QTextCursor(&m_document);

	m_popupDeleteTimer.setInterval(PopupTimeout);
	connect(&m_popupDeleteTimer, SIGNAL(timeout()), this, SLOT(deletePopup()));
}

PostWidget::~PostWidget()
{
	if(m_popup)
		delete m_popup;
}

PostItemView* PostWidget::piv()
{
	return m_piv;
}

void PostWidget::setPiv(PostItemView* piv)
{
	m_piv = piv;
}

QString PostWidget::text()
{
	return m_document.toHtml();
}

PostId PostWidget::postId()
{
	return m_postId;
}

void PostWidget::setPostId(const PostId& id)
{
	m_postId = id;
}

Wishmaster::Board* PostWidget::board()
{
	return m_board;
}

ThreadId PostWidget::threadId()
{
	return m_threadId;
}

void PostWidget::setBoard(Wishmaster::Board* b)
{
	m_board = b;
}

void PostWidget::setThreadId(const ThreadId& id)
{
	m_threadId = id;
}

void PostWidget::paintEvent(QPaintEvent* event)
{
	QPainter p(this);
	doPaint(&p, rect());
	QWidget::paintEvent(event);
}

QPixmap PostWidget::makePixmap(const QSize& optrect)
{
	QRect originalRect = QRect(QPoint(0, 0), optrect);
	originalRect.setWidth(width());
	QPixmap p(originalRect.size());
	p.fill(QColor(0, 0, 0, 0));
	QPainter painter(&p);

	QRect r = originalRect;

	painter.save();
	r.adjust(0, 0, -1, -1);
	QPen pen;
	QBrush brush(Qt::SolidPattern);
	pen.setColor(postStyle()->postBorderColor());
	brush.setColor(postStyle()->postBackgroundColor());
	pen.setWidth(1);
	painter.setPen(pen);
	painter.setBackgroundMode(Qt::OpaqueMode);
	painter.setBrush(brush);
	painter.drawRoundedRect(r, postStyle()->borderRadius(), postStyle()->borderRadius());
	painter.restore();

	QFont f = postStyle()->postFont();
	f.setPointSize(f.pointSize() * m_piv->fontSizeMultiplier());
	painter.setFont(f);
	Wishmaster::PostPtr post = m_thread->lookupPost(m_postId);
	if(!post)
	{
		QString txt = tr("Post not found");
		pen.setColor(QColor(0, 0, 0));
		painter.setPen(pen);
		r = painter.boundingRect(r, Qt::AlignCenter | Qt::AlignVCenter, txt);
		painter.drawText(r, Qt::AlignCenter | Qt::AlignVCenter, txt);
		return p;
	}

	if((post->visibility() != Hide) &&
	   (post->visibility() != HideForever))
	{
		// Draw text and picture
		r = m_textRect;
		r.translate(originalRect.x(), originalRect.y());
		painter.save();
		painter.translate(r.x(), r.y());
		pen.setColor(QColor(0, 0, 0));
		painter.setPen(pen);
		QAbstractTextDocumentLayout::PaintContext ctx;
		ctx.cursorPosition = -1;

		QAbstractTextDocumentLayout::Selection sel;
		sel.cursor = m_selection;
		sel.format.setForeground(QApplication::palette().highlightedText());
		sel.format.setBackground(QApplication::palette().highlight());
		ctx.selections.append(sel);

		m_document.documentLayout()->draw(&painter, ctx);
		painter.restore();
	}

	// Draw horizontal line
	painter.save();
	pen.setColor(QColor(0, 0, 0));
	pen.setWidth(1);
	painter.setPen(pen);
	QPoint p1 = QPoint(originalRect.topLeft().x() + 2, originalRect.topLeft().y() + m_xynta - 1);
	QPoint p2 = QPoint(originalRect.topRight().x() - 2, originalRect.topRight().y() + m_xynta - 1);
	painter.drawLine(p1, p2);
	painter.restore();

	painter.save();

	foreach(const PostWidgetElementPtr& el, m_elements)
	{
		QRect r = el->rect();
		r.translate(originalRect.x(), originalRect.y());
		if(!el->pixmap().isNull())
		{
			painter.drawPixmap(r, el->pixmap());
		}
		else if(!el->text().isEmpty())
		{
			if((el->id() == m_activeElement) && (el->id() != pweUnknown))
				painter.setPen(QPen(el->hoverColor()));
			else
				painter.setPen(QPen(el->normalColor()));
			painter.setFont(el->font());
			painter.drawText(r, el->text());
		}
	}


	painter.setPen(pen);
	painter.setFont(postStyle()->noteFont());

	QList<PostId> replies = post->replies();
	if(m_referenceListRect.height() > 0)
	{
		QFontMetrics noteMetrics(postStyle()->noteFont());
		r = m_referenceListRect;
		r.translate(originalRect.x(), originalRect.y());
		pen.setColor(postStyle()->postBorderColor());
		painter.setPen(pen);
		QBrush brush(Qt::SolidPattern);
		brush.setColor(postStyle()->postBackgroundColor());
		painter.setBrush(brush);
		painter.drawRoundedRect(r, 1, 1);

		pen.setColor(postStyle()->linkColor());
		painter.setPen(pen);
		int i = 0;
		foreach(const PostId& reply, replies)
		{
			QRect r2 = m_referenceListRect;
			r2.setHeight(noteMetrics.height());
			r2.translate(originalRect.x(), originalRect.y() + noteMetrics.height() * i + ContentMargin);
			painter.drawText(r2, Qt::AlignCenter | Qt::AlignVCenter, QString(">>%1").arg(reply.postId()));
			i++;
		}
	}

	painter.restore();
	return p;
}

int PostWidget::headerWidth()
{
	Wishmaster::PostPtr post = m_thread->lookupPost(m_postId);
	if(!post)
		return 0;

	QImage del = postStyle()->deleteIcon();
	QImage hide = postStyle()->hideIcon();
	QImage info = postStyle()->infoIcon();

	QFontMetrics headerFontMetrics = QFontMetrics(postStyle()->headerFont());

	int w = ContentMargin + del.width() + hide.width() +
			info.width() + headerFontMetrics.boundingRect(headerText()).width() +
			2 * HeaderSpacing;

	QList<PostId> replies = post->replies();
	if(replies.count() > 0)
		w += ReplyListWidth;
	return w;
}

void PostWidget::doPaint(QPainter* painter, const QRect& optrect)
{
	QRect originalRect = optrect;
	originalRect.setWidth(width());
	QPixmap p;
	if(!QPixmapCache::find(m_key, &p))
	{
		p = makePixmap(optrect.size());
		m_key = QPixmapCache::insert(p);
	}
	painter->drawPixmap(originalRect, p);
}

void PostWidget::setText(Wishmaster::PostPtr post)
{
	if(!post)
	{
		return;
	}

	QString styleSheet = QString("a { color: %1; } html { color: %2; }").arg(postStyle()->linkColor().name()).arg(postStyle()->textColor().name());
	m_document.setDefaultStyleSheet(styleSheet);
	m_key = QPixmapCache::Key();
	m_postName = post->name();
	m_postTopic = post->topic();
	QString resultText = post->text();
	for(int i = 0; i < post->attachmentCount(); i++)
	{
		QImage thumb = post->attachment(i)->thumbnail();
		if(!thumb.isNull())
		{
			QUrl url;
			url.setHost(m_board->getParent()->getHost());
			if(!m_imageHideMode)
			{
				if(!post->isExpanded())
				{
					m_document.setImage(i, thumb);
					url.setPath(QString::number(i));
					resultText.prepend(QString("<table style=\"float: left;\" cellspacing=12><tr><td><a href=\"img://%1\"><img src=\"%2\" style=\"float: left;\" /></a></td></tr></table>").arg(i).arg(url.toString()));
				}
				else
				{
					if(post->attachment(i)->type().startsWith("image"))
					{
						m_document.setImage(i, post->attachment(i)->image());
					}
				}
			}
		}
	}
	if(!post->extra("signature").id.isEmpty())
	{
		resultText += "<br>";
		resultText += QString("<font color=\"#0000ff\">%1</font>").arg(post->extra("signature").description);
	}
	resultText.prepend("<html>").append("</html>");
	m_document.setHtml(resultText);
	if(m_piv)
		setWidth(m_piv->maxItemWidth());
}

void PostWidget::calculateGeometries(QSize size)
{
	Q_UNUSED(size);
	Wishmaster::PostPtr post = m_thread->lookupPost(m_postId);
	if(!post)
		return;

	m_elements.clear();

	QImage del = postStyle()->deleteIcon();
	QImage info = postStyle()->infoIcon();
	QFontMetrics headerFontMetrics = QFontMetrics(postStyle()->headerFont());

	int offset = ContentMargin;
	PostWidgetElementPtr elDelete = PostWidgetElementPtr(new PostWidgetElement(pweDelete, QRect(offset, ContentMargin, del.width(), del.height())));
	elDelete->setPixmap(QPixmap::fromImage(del));
	m_elements.append(elDelete);
	offset += del.width();

	if((post->visibility() != Hide) &&
	   (post->visibility() != HideForever))
	{
		QImage hide = postStyle()->hideIcon();
		PostWidgetElementPtr elHide = PostWidgetElementPtr(new PostWidgetElement(pweHide, QRect(offset, ContentMargin, hide.width(), hide.height())));
		elHide->setPixmap(QPixmap::fromImage(hide));
		m_elements.append(elHide);
		offset += hide.width();
	}
	else
	{
		QImage unhide = postStyle()->unhideIcon();
		PostWidgetElementPtr elUnhide = PostWidgetElementPtr(new PostWidgetElement(pweUnhide, QRect(offset, ContentMargin, unhide.width(), unhide.height())));
		elUnhide->setPixmap(QPixmap::fromImage(unhide));
		m_elements.append(elUnhide);
		offset += unhide.width();
	}

	if(post->extraList().count() > 0)
	{
		PostWidgetElementPtr elInfo = PostWidgetElementPtr(new PostWidgetElement(pweInfo, QRect(offset, ContentMargin, info.width(), info.height())));
		elInfo->setPixmap(QPixmap::fromImage(info));

		QString text;
		text.append("<ul>");
		foreach(const QString& s, post->extraList())
		{
			Wishmaster::ExtraInfo extra = post->extra(s);
			if(extra.description.isEmpty())
				continue;
			text.append("<li>");
			text.append(extra.description);
			text.append("</li>");
		}
		text.append("</ul>");
		if(text != "<ul></ul>")
			elInfo->setTooltip(text);

		m_elements.append(elInfo);
		offset += info.width();
	}
	offset += info.width() + HeaderSpacing;

	int headerLine = m_xynta - 2 * ContentMargin;
	QRect r;
	r = QRect(QPoint(offset, headerLine - headerFontMetrics.ascent()), headerFontMetrics.boundingRect(post->name()).size() + QSize(2 * ContentMargin, 0));
	PostWidgetElementPtr elName = PostWidgetElementPtr(new PostWidgetElement(pweUnknown, r, post->name()));
	elName->setFont(postStyle()->headerFont());
	elName->setNormalColor(postStyle()->headerColor());
	m_elements.append(elName);
	offset += r.width() + HeaderSpacing;

	QString postid = QString("#%1").arg(post->id().postId());
	r = QRect(QPoint(offset, headerLine - headerFontMetrics.ascent()), headerFontMetrics.boundingRect(postid).size() + QSize(2 * ContentMargin, 0));
	PostWidgetElementPtr elPostId = PostWidgetElementPtr(new PostWidgetElement(pwePostId, r, postid));
	elPostId->setFont(postStyle()->headerFont());
	elPostId->setNormalColor(postStyle()->linkColor());
	elPostId->setHoverColor(postStyle()->linkHoverColor());
	m_elements.append(elPostId);
	offset += r.width() + HeaderSpacing;

	if(!post->topic().isEmpty())
	{
		r = QRect(QPoint(offset, headerLine - headerFontMetrics.ascent()), headerFontMetrics.boundingRect(post->topic()).size() + QSize(2 * ContentMargin, 0));
		PostWidgetElementPtr elHeader = PostWidgetElementPtr(new PostWidgetElement(pweUnknown, r, post->topic()));
		elHeader->setFont(postStyle()->headerFont());
		elHeader->setNormalColor(postStyle()->headerColor());
		m_elements.append(elHeader);
		offset += r.width() + HeaderSpacing;
	}

	if(post->timestamp().isValid())
	{
		QString timeString = post->timestamp().toString();
		r = QRect(QPoint(offset, headerLine - headerFontMetrics.ascent()), headerFontMetrics.boundingRect(timeString).size() + QSize(2 * ContentMargin, 0));
		PostWidgetElementPtr elTimestamp = PostWidgetElementPtr(new PostWidgetElement(pweTimestamp, r, timeString));
		elTimestamp->setFont(postStyle()->headerFont());
		elTimestamp->setNormalColor(postStyle()->headerColor());
		m_elements.append(elTimestamp);
		offset += r.width() + HeaderSpacing;
	}

	QList<PostId> replies = post->replies();
	if(replies.count() > 0)
	{
		QFontMetrics noteMetrics(postStyle()->noteFont());
		QString txt = tr("Replies: %1").arg(replies.count());
		r = QRect(QPoint(offset, headerLine - noteMetrics.ascent()), noteMetrics.boundingRect(txt).size() + QSize(6 * ContentMargin, 0));
		PostWidgetElementPtr elReplyCount = PostWidgetElementPtr(new PostWidgetElement(pweReferenceCount, r, txt));
		elReplyCount->setFont(postStyle()->noteFont());
		elReplyCount->setNormalColor(postStyle()->linkColor());
		elReplyCount->setHoverColor(postStyle()->linkHoverColor());
		m_elements.append(elReplyCount);
		offset += r.width() + HeaderSpacing;

		m_referenceListRect = QRect(QPoint(r.x() - ReplyListWidth / 2, m_xynta + ContentMargin), QSize(ReplyListWidth, 0));
	}
	m_headerWidth = offset;
}

void PostWidget::updateFont()
{
	QFont f = postStyle()->postFont();
	f.setPointSize(f.pointSize() * m_piv->fontSizeMultiplier());
	m_document.setDefaultFont(f);
}

void PostWidget::adjustWidth()
{
	int newWidth = 0;
	updateFont();
	if((!m_piv) || (m_piv->isAdjustSize()))
	{
		newWidth = m_document.idealWidth();
		if(newWidth < m_headerWidth)
			newWidth = m_headerWidth;
		if(newWidth > m_piv->maxItemWidth())
			newWidth = m_piv->maxItemWidth();
	}
	else
		newWidth = m_piv->maxItemWidth();
	m_document.setTextWidth(newWidth);
	if(1.5 * m_document.size().height() > m_document.size().width())
	{
		m_document.setTextWidth(std::min((int)(1.5 * m_document.size().width()), m_piv->maxItemWidth()));
	}
	newWidth = m_document.textWidth() + 20;
	Wishmaster::PostPtr post = m_thread->lookupPost(m_postId);
	if(post && ((post->visibility() == Hide) || (post->visibility() == HideForever)))
		resize(newWidth, m_xynta);
	else
		resize(newWidth, m_document.size().height() + m_xynta);
	m_textRect = QRect(QPoint(0, 0), m_document.size().toSize());
	m_textRect.adjust(10, 2 + m_xynta, -10, 2);
	m_key = QPixmapCache::Key();
}

void PostWidget::setWidth(int w)
{
	adjustWidth();
	calculateGeometries(size());
}

void PostWidget::update()
{
	Wishmaster::PostPtr post = m_thread->lookupPost(m_postId);
	if(post)
		setText(post);
	QWidget::update();
}

void PostWidget::recalcGeometry()
{
	setWidth(size().width());
	calculateGeometries(size());
}

QString PostWidget::linkAt(const QPoint& p)
{
	QPoint p2 = p;
	p2.setX(p2.x() - m_textRect.left());
	p2.setY(p2.y() - m_textRect.top());
	return m_document.documentLayout()->anchorAt(p2);
}

QString PostWidget::selectedText(const QPoint& p)
{
	return m_selection.selectedText();
}

void PostWidget::mouseMove(const QPoint& p, const QPoint& global)
{
	PostWidget* pop = popup(QPoint(p.x(), p.y()));
	if(pop)
	{
		PostItemView* myparent = m_piv;
		pop->setPiv(myparent);
		pop->setParent(myparent);
		pop->setWidth(width());
		pop->updateFont();
		pop->show();
		pop->setMouseTracking(true);
		if(m_popupChanged)
		{
			QPoint target;
			if(m_chainLeader)
				target = QPoint(3, global.y() + 5);
			else
				target = QPoint(3, pos().y() + p.y() + 4);
			if(!myparent->rect().contains(target + pop->rect().bottomRight()))
				target -= QPoint(0, pop->rect().height() + 3);
			pop->move(target);
		}
	}
	int activeElement = pweUnknown;
	foreach(const PostWidgetElementPtr& el, m_elements)
	{
		if(el->rect().contains(p))
		{
			activeElement = el->id();
			break;
		}
	}
	if(activeElement != m_activeElement)
	{
		m_key = QPixmapCache::Key();
		m_activeElement = activeElement;
	}
	if(m_sel)
	{
		QPoint p2 = QPoint(p.x(), p.y() - m_xynta);
		p2.setX(p2.x() - m_textRect.left());
		m_selection.setPosition(m_document.documentLayout()->hitTest(p2, Qt::FuzzyHit), QTextCursor::KeepAnchor);
		m_key = QPixmapCache::Key();
	}
	QWidget::update();
}

void PostWidget::enterEvent(QEvent* ev)
{
	emit signalMouseEnter();
}

void PostWidget::leaveEvent(QEvent* ev)
{
	emit signalMouseLeft();
}

void PostWidget::mouseLeft()
{
	m_key = QPixmapCache::Key();
	m_activeElement = pweUnknown;
	m_referenceListRect.setHeight(0);
	if(m_popup)
	{
		m_popupLink.clear();
		delete m_popup;
		m_popup = 0;
	}
	QWidget::update();
}

void PostWidget::mousePress(const QPoint& p)
{
	if(m_referenceListRect.contains(p))
		return;
	QString link = linkAt(p);
	if(link.startsWith("img://"))
	{
		emit postDownloadAttachment(m_postId, link.mid(6).toInt());
		return;
	}
	else
	{
		log(llDebug, "PostWidget::mouseClick :(%s)", qPrintable(link));
		if(!link.isEmpty())
		{
			emit linkClicked(link);
		}
	}
	QPoint p2 = QPoint(p.x() - m_textRect.left(), p.y() - m_textRect.top());
	m_selection.setPosition(m_document.documentLayout()->hitTest(p2, Qt::FuzzyHit), QTextCursor::MoveAnchor);
	m_sel = true;
}

void PostWidget::mouseClick(const QPoint& p)
{
	m_sel = false;
	switch(m_activeElement)
	{
	case pweDelete:
		emit postDelete(m_postId);
		break;
	case pweHide:
	case pweUnhide:
		emit postHide(m_postId);
		break;
	case pwePostId:
		emit postIdClicked(m_postId);
		break;
	case pweReferenceCount:
		if(m_referenceListRect.height() > 0)
			m_referenceListRect.setHeight(0);
		else
		{
			Wishmaster::PostPtr post = m_thread->lookupPost(m_postId);
			QFontMetrics noteMetrics(postStyle()->noteFont());
			m_referenceListRect.setHeight(post->replies().count() * noteMetrics.height() + 2 * ContentMargin);
		}
		break;
	}
	if(m_referenceListRect.contains(p))
	{
		QFontMetrics noteMetrics(postStyle()->noteFont());
		Wishmaster::PostPtr post = m_thread->lookupPost(m_postId);
		int itemnum = (p.y() - m_referenceListRect.top() - ContentMargin) / noteMetrics.height();
		if(itemnum < 0 || itemnum >= post->replies().count())
		{
			log(llDebug, "Invalid itemnum: %d (%d/%d)", itemnum, p.y(), m_referenceListRect.top() );
			return;
		}
		emit postLinkClicked(post->replies().at(itemnum));
	}


	QWidget::update();
}

PostWidget* PostWidget::popup(const QPoint& p)
{
	m_popupChanged = false;
	QString link = linkAt(p);
	if(link.isEmpty())
	{
		if(m_popup && !m_popupDeleteTimer.isActive())
		{
			m_popupDeleteTimer.start();
		}
	}
	else
	{
		m_popupDeleteTimer.stop();
		if(link == m_popupLink)
			return m_popup;
		m_popupLink = link;
		//log(llDebug, "PostWidget::popup: %s", qPrintable(link));
		PostId targetPostId = m_board->getPostID(link, m_threadId);
		if(targetPostId.isValid())
		{
			if(m_popup)
			{
				delete m_popup;
				m_popup = 0;
			}
			m_popup = new PostWidget(m_board, m_threadId, targetPostId, 0, m_imageHideMode, postStyle());
			connect(m_popup, SIGNAL(postDelete(PostId)), m_piv, SLOT(postDelete(PostId)));
			connect(m_popup, SIGNAL(postHide(PostId)), m_piv, SLOT(postHide(PostId)));
			connect(m_popup, SIGNAL(postIdClicked(PostId)), m_piv, SLOT(postReply(PostId)));
			connect(m_popup, SIGNAL(postLinkClicked(PostId)), m_piv, SLOT(postLinkClicked(PostId)));
			connect(m_popup, SIGNAL(postDownloadAttachment(PostId, int)), m_piv, SLOT(postDownloadAttachment(PostId, int)));
			connect(m_popup, SIGNAL(signalMouseEnter()), this, SLOT(popupMouseEnter()));
			connect(m_popup, SIGNAL(signalMouseLeft()), this, SLOT(popupMouseLeft()));
			m_popupChanged = true;
		}
	}

	return m_popup;
}

void PostWidget::popupMouseLeft()
{
	m_popupDeleteTimer.start();
}

void PostWidget::popupMouseEnter()
{
	m_popupDeleteTimer.stop();
	emit signalMouseEnter();
}

void PostWidget::deletePopup()
{
	m_popupChanged = true;
	m_popupLink.clear();
	delete m_popup;
	m_popup = 0;
	m_popupDeleteTimer.stop();
}

void PostWidget::mouseMoveEvent(QMouseEvent* event)
{
	if(!m_inMMEvent)
	{
		m_inMMEvent = true;
		mouseMove(event->pos(), event->pos());
		m_inMMEvent = false;
	}
	QWidget::mouseMoveEvent(event);
}

bool PostWidget::isChainLeader()
{
	return m_chainLeader;
}

void PostWidget::setChainLeader(bool cl)
{
	m_chainLeader = cl;
}

void PostWidget::mousePressEvent(QMouseEvent* event)
{
	mousePress(event->pos());
}

void PostWidget::mouseReleaseEvent(QMouseEvent* event)
{
	mouseClick(event->pos());
}

bool PostWidget::event(QEvent* event)
{
	if(event->type() == QEvent::ToolTip)
	{
		QHelpEvent* e = static_cast<QHelpEvent*>(event);
		help(e->pos(), e->globalPos());
	}
	return QWidget::event(event);
}

void PostWidget::help(const QPoint& p, const QPoint& global)
{
	foreach(const PostWidgetElementPtr& el, m_elements)
	{
		if(el->rect().contains(p))
		{
			if(el->tooltip().isEmpty())
				break;
			QToolTip::showText(global, el->tooltip());
			return;
		}
	}
	QToolTip::hideText();
}

void PostWidget::resetText()
{
	Wishmaster::PostPtr post = m_thread->lookupPost(m_postId); 
	setText(post);
}

void PostWidget::resetSelection()
{
	m_selection.setPosition(0, QTextCursor::MoveAnchor);
}

void PostWidget::setImageHideMode(bool s)
{
	m_imageHideMode = s;
}

bool PostWidget::isImageHideMode()
{
	return m_imageHideMode;
}

void PostWidget::setPostStyle(const PostStylePtr& style)
{
	m_postStyle = style;
}

PostStylePtr PostWidget::postStyle() const
{
	return m_postStyle;
}

QString PostWidget::headerText()
{
	Wishmaster::PostPtr post = m_thread->lookupPost(m_postId);
	QString result = post->name() + '#' + QString::number(post->id().postId()) +
			QString(3, QChar(0x2001)) + post->topic();
	if((post->visibility() != Hide) &&
	   (post->visibility() != HideForever))
		result.append(tr(" (Hidden)"));
	return result;
}

